package com.pearlsoft.rms.vcenter;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

import com.pearlsoft.rms.MetricResult;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.PerfCounterInfo;
import com.vmware.vim25.PerfEntityMetric;
import com.vmware.vim25.PerfEntityMetricBase;
import com.vmware.vim25.PerfMetricId;
import com.vmware.vim25.PerfMetricIntSeries;
import com.vmware.vim25.PerfMetricSeries;
import com.vmware.vim25.PerfQuerySpec;
import com.vmware.vim25.PerfSampleInfo;
import com.vmware.vim25.VimPortType;

/**
 * 
 * @author rainshow
 * @Created 2012-5-10 下午04:00:21
 */

@Service("realtime")
public class Realtime extends VcenterClient {

    private static Log logger = LogFactory.getLog(Realtime.class);

    public Realtime() {
    }

    /**
     * This method initializes all the performance counters available on the
     * system it is connected to. The performance counters are stored in the
     * hashmap counters with group.counter.rolluptype being the key and id being
     * the value.
     */

    public MetricResult doRealTime(String vmName, String groupname, String countername, int interval) throws Exception {
        List<List<Long>> data = new ArrayList<List<Long>>();
        ManagedObjectReference vmmor = getVmByVMname(vmName);
        counterInfo(getConnection().getPerfManager());
        if (vmmor != null) {
            PerfCounterInfo pci = getCounterInfo(groupname, countername, null, null);
            if (pci == null) {
                logger.error("Incorrect Group Name and Countername specified");
                return new MetricResult();
            }
            VimPortType vimPort = this.getConnection().getVimPort();
            List<PerfMetricId> listpermeid = vimPort.queryAvailablePerfMetric(getConnection().getPerfManager(), vmmor,
                    null, null, new Integer(interval));
            PerfMetricId ourCounter = null;
            for (int index = 0; index < listpermeid.size(); ++index) {
                if (listpermeid.get(index).getCounterId() == pci.getKey()) {
                    ourCounter = listpermeid.get(index);
                    break;
                }
            }
            if (ourCounter == null) {
                logger.warn("No data on Host to collect.");
                return new MetricResult(pci.getUnitInfo().getSummary());
            }
            PerfQuerySpec qSpec = new PerfQuerySpec();
            qSpec.setEntity(vmmor);
            qSpec.setMaxSample(new Integer(10));
            qSpec.getMetricId().addAll(Arrays.asList(new PerfMetricId[] { ourCounter }));
            qSpec.setIntervalId(interval);
            List<PerfQuerySpec> qSpecs = new ArrayList<PerfQuerySpec>();
            qSpecs.add(qSpec);
            List<PerfEntityMetricBase> values = vimPort.queryPerf(getConnection().getPerfManager(), qSpecs);
            if (values != null) {
                for (int i = 0; i < values.size(); ++i) {
                    List<PerfMetricSeries> listpems = ((PerfEntityMetric) values.get(i)).getValue();
                    List<PerfSampleInfo> listinfo = ((PerfEntityMetric) values.get(i)).getSampleInfo();

                    logger.info("Sample time range: " + listinfo.get(0).getTimestamp().toString() + " - "
                            + listinfo.get(listinfo.size() - 1).getTimestamp().toString());
                    for (int vi = 0; vi < listpems.size(); ++vi) {
                        if (listpems.get(vi) instanceof PerfMetricIntSeries) {
                            PerfMetricIntSeries val = (PerfMetricIntSeries) listpems.get(vi);
                            List<Long> lislon = val.getValue();
                            data.add(lislon);
                        }
                    }
                }
            }
            return new MetricResult(pci.getUnitInfo().getLabel(), data);
        } else {
            logger.warn("Virtual Machine " + vmName + " not found");
            return new MetricResult();
        }
    }

    public static void main(String[] args) throws Throwable {
        ApplicationContext context = new ClassPathXmlApplicationContext(
                new String[] { "classpath:applicationContext.xml" });
        Realtime r = context.getBean("realtime", Realtime.class);
        List<List<Long>> data = r.doRealTime("AD", "mem", "usage", 20).getData();
        if (!data.isEmpty()) {
            System.out.println(data.get(0));
        }
    }
}